home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 44 / Amiga Format CD44 (1999-08-26)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-10].iso / -in_the_mag- / basics / blitz / hookfunc.lha / hookfunc.bb2 next >
Text File  |  1998-12-22  |  7KB  |  140 lines

  1. ; Description:  How to use hooks in Blitz. This one is an example for the ASL
  2. ;               screenmode requester and it works. Working parts by Paul "Mildred"
  3. ;               West.
  4. ;               You need amigalibsii.res resident.
  5. ;
  6. ;               Note that some things aren't explained fully (i.e. the tags
  7. ;               for the screenmode requester). You should look at the Autodocs
  8. ;               for these.
  9.  
  10. ; Type:         SYSTEM
  11.  
  12. ; These defines should be in amigalibsii.res, but they appear not to be
  13. #DTAG_DISP=$80000000
  14. #DTAG_DIMS=$80001000
  15. #DTAG_MNTR=$80002000
  16. #DTAG_NAME=$80003000
  17.  
  18. ; The initial values for the width and height when opening the screenmode
  19. ; requester (silly really, as we won't see them - see later in code)
  20. PrefDisplayWidth.w=320
  21. PrefDisplayHeight.w=240
  22.  
  23. DEFTYPE.Hook myhook             ; The hook for ASL tag as &myhook
  24. myhook\h_Entry=?hook            ; Set address of hook stub which sorts out registers and calls Blitz function
  25. myhook\h_SubEntry = ?hook_jump  ; Set address of Blitz function. NB That you must have a label directly before the function
  26. PutReg a5,myhook\h_Data         ; Store the global variables base
  27.  
  28. ; Set up some tags for the ASL screenmode requester
  29. Dim SMRtags.TagItem(18)
  30. SMRtags(0)\ti_Tag=#ASLSM_InitialLeftEdge,160                    ; Initial left edge of requester
  31. SMRtags(1)\ti_Tag=#ASLSM_InitialTopEdge,0                       ; Initial top edge of requester
  32. SMRtags(2)\ti_Tag=#ASLSM_InitialWidth,300                       ; Initial width of requester
  33. SMRtags(3)\ti_Tag=#ASLSM_InitialHeight,600                      ; Initial height of requester
  34. SMRtags(4)\ti_Tag=#ASLSM_InitialDisplayID,$21000                ; Initial screenmode (if present, PAL:Lowres)
  35. SMRtags(5)\ti_Tag=#ASLSM_InitialDisplayDepth,8                  ; Initial depth of screen (in bitplanes/bits per pixel)
  36. SMRtags(6)\ti_Tag=#ASLSM_InitialDisplayWidth,PrefDisplayWidth   ; Initial width of desired screen
  37. SMRtags(7)\ti_Tag=#ASLSM_InitialDisplayHeight,PrefDisplayHeight ; Initial height of desired screen
  38. SMRtags(8)\ti_Tag=#ASLSM_InitialOverscanType,2                  ; Initial overscan type in cycle gadget (2 = #OSCAN_STANDARD)
  39. SMRtags(9)\ti_Tag=#ASLSM_InitialInfoOpened,1                    ; Set information box to open
  40. SMRtags(10)\ti_Tag=#ASLSM_InitialInfoLeftEdge,350               ; Initial left edge of info box
  41. SMRtags(11)\ti_Tag=#ASLSM_InitialInfoTopEdge,50                 ; Initial top edge of info box
  42. SMRtags(12)\ti_Tag=#ASLSM_DoDepth,0                             ; Don't show depth requester to user
  43. SMRtags(13)\ti_Tag=#ASLSM_DoOverscanType,1                      ; Show overscan cycle gadget to user
  44. SMRtags(14)\ti_Tag=#ASLSM_DoWidth,1                             ; Show width gadget to user
  45. SMRtags(15)\ti_Tag=#ASLSM_DoHeight,1                            ; Show height gadget to user
  46. SMRtags(16)\ti_Tag=#ASLSM_FilterFunc,&myhook                    ; Set hook for this function
  47. SMRtags(17)\ti_Tag=#TAG_END                                     ; End of tag list
  48.  
  49. ; Initialise and allocate a requester for the screenmode
  50. *sreq.ScreenModeRequester=0
  51. *sreq=AllocAslRequest_(#ASL_ScreenModeRequest,&SMRtags(0)\ti_Tag)
  52.  
  53. ; Display the requester
  54. ok.b=AslRequest_(*sreq,&SMRtags(0)\ti_Tag)
  55.  
  56. ; If the return value was not 0 (therefore a success)
  57. If ok<>0
  58.     ; Display the returned values in the structure allocated earlier
  59.     ; and wait for 3 seconds
  60.     NPrint *sreq\sm_DisplayID
  61.     NPrint *sreq\sm_DisplayWidth
  62.     NPrint *sreq\sm_DisplayHeight
  63.     Delay_ 150
  64. EndIf
  65. If (*sreq) Then FreeAslRequest_(*sreq)  ; If the screenmode allocation succeeded, then free theallocated memory
  66.  
  67.  
  68. ;*************************************************************************
  69. ; This is the Function that the hook will call.  Put the label before
  70. ; the Statement/Function you want To jump To. Note that you need to put
  71. ; Runnerrsoff and Runerrson around the statement or function.
  72. ;
  73. ; In this implementation, the ASL screenmode requester uses a hook to decide
  74. ; which screenmodes to display in the selection list. This function returns
  75. ; true for ASL to display the screenmode and false to not display the screenmode.
  76. ; The hook (and therefore this function) are called for every screenmode that
  77. ; ASL screenmode requester finds.
  78. Runerrsoff
  79. hook_jump:
  80. Function.l hook{*dahook.Hook, modeID.l, *smr.ScreenModeRequester}
  81.     DEFTYPE.DisplayInfo   DisInfoBuf ; Buffer to receive information about mode display
  82.     DEFTYPE.DimensionInfo DimInfoBuf ; Buffer to receive information about mode dimensions
  83.     DEFTYPE.MonitorInfo   MonInfoBuf ; Buffer to receive information about monitor (driver)
  84.     DEFTYPE.NameInfo      NamInfoBuf ; Buffer to receive information about mode name
  85.  
  86.     ; Gets a handle to a record of display information for the screenmode in question
  87.     IDhandle.l=FindDisplayInfo_(modeID)
  88.     ; Fill in the various buffers about this screenmode, using the newly
  89.     ; gotten handle
  90.     GetDisplayInfoData_ IDhandle,&DisInfoBuf,SizeOf.DisplayInfo,#DTAG_DISP,0
  91.     GetDisplayInfoData_ IDhandle,&DimInfoBuf,SizeOf.DimensionInfo,#DTAG_DIMS,0
  92.     GetDisplayInfoData_ IDhandle,&MonInfoBuf,SizeOf.MonitorInfo,#DTAG_MNTR,0
  93.     GetDisplayInfoData_ IDhandle,&NamInfoBuf,SizeOf.NameInfo,#DTAG_NAME,0
  94.  
  95.     ; Do tests. True=Mode is valid, False=mode is invalid. In these test, any mode
  96.     ; with a maximum horizontal width of less than 400 is rejected (i.e. PAL and
  97.     ; NTSC Lowres modes)
  98.     If DimInfoBuf\Nominal\MaxX < 400
  99.         Function Return False
  100.     Else
  101.         Function Return True
  102.     End If
  103. End Function
  104. Runerrson
  105. ;*************************************************************************
  106.  
  107.  
  108. ;*************************************************************************
  109. Goto HookSkip                       ; This is done so that hook code does not get
  110.                                     ; executed out of place
  111.  
  112. ; Code for calling the higher level hook functions. This piece of code is used
  113. ; for all hooks. Basically it puts whats in A0 (usually the *hook structure) into
  114. ; D0, A1 into D1 and A2 into D2. What this means is that within your high level
  115. ; function, you should have three parameters. These parameters must match up with
  116. ; what the Autodocs say will be passed in the address registers (given that they
  117. ; are put into the data registers). Remember that in Blitz, the parameters
  118. ; are in order of data register D0 first parameter, and so on.
  119. ; This hook will also return a value in D), which is the value returned by the
  120. ; high level function. Some hook applications may need this, others may not.
  121. hook:   MOVEM.l d1-d7/a0-a6,-(a7)   ; Save registers to stack (NOT D0!!!)
  122.  
  123.         MOVE.l a0,d0                ; These three moves put the hook parameters
  124.         MOVE.l a1,d1                ; (which are in A0-A2) into the data registers,
  125.         MOVE.l a2,d2                ; so that the Blitz function can access them
  126.  
  127.         MOVEA.l 16(a0),a5           ; Restore the global variable base
  128.         MOVEA.l 12(a0),a3           ; Get the address pointed to by the h_SubEntry field of the Hook structure
  129.         LEA.l   6(a3),a3            ; Get the address to jump to (adress of high level function)
  130.         JSR     (a3)                ; Go do it!!
  131.  
  132.         ; The value is returned in d0 from the function. As this is where
  133.         ; we want it, nothing is done, and the hook returns.
  134.         MOVEM.l (a7)+,d1-d7/a0-a6   ; Restore registers from stack (NOT D0, we want to keep the return value)
  135.         RTS
  136.  
  137. HookSkip
  138. End
  139.  
  140.